﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nollie.Storage;
using System.Threading;
using Nollie.Storage.Database;
using Nollie.Utilities;

namespace Nollie.CacheTypes.Mixed
{
	public class MixedCache : ICache, IMixedCache
	{
		private Dictionary<string, Partition> _partitions = new Dictionary<string, Partition>();
		private IDatabaseStorage _cacheStorage;
		private ReaderWriterLockSlim _locker = new ReaderWriterLockSlim();
		
		public MixedCache(CacheConfiguration configuration)
		{
			_cacheStorage = new SqlServerStorage(configuration);
		}

		public IPartition GetDbPartition(string partitionName)
		{
			return GetPartition(partitionName, PartitionTypes.Db, 0);
		}
		public IPartition GetMixedPartition(string partitionName, int inMemoryCacheCapacity)
		{
			return GetPartition(partitionName, PartitionTypes.Mixed, inMemoryCacheCapacity);
		}
		public IPartition GetMemPartition(string partitionName, int inMemoryCacheCapacity)
		{
			return GetPartition(partitionName, PartitionTypes.Mem, inMemoryCacheCapacity);
		}
		private IPartition GetPartition(string partitionName, PartitionTypes cacheType, int memCacheCapacity)
		{
			using (var lockHelper = new ReaderLockHelper(_locker))
			{
				if (_partitions.ContainsKey(partitionName))
					return _partitions[partitionName];
			}

			using (var lockHelper = new WriterLockHelper(_locker))
			{
				var partition = new Partition(this, _cacheStorage, partitionName, cacheType, memCacheCapacity);

				_partitions.Add(partitionName, partition);

				return partition;
			}
		}
		public void ClearAllPartitions()
		{
			using (var lockHelper = new ReaderLockHelper(_locker))
			{
				foreach (var partition in _partitions)
					partition.Value.Clear();
			}

			_cacheStorage.ClearAllPartitions();
		}
		public void RemoveByTag(string tag)
		{
			using (var lockHelper = new ReaderLockHelper(_locker))
			{ 		
				foreach (var partition in _partitions)
					partition.Value.RemoveByTagFromMemCache(tag);
			}

			_cacheStorage.RemoveByTag(tag);
		}
	}
}
